#include<stdio.h>


//节点的结构体
typedef struct button
{
	int data;
  	struct button *Next;  
}Button_t;


//头结点 指针
static struct button* Head_Button = NULL;



//打印这个链表   因为头是全局变量  所以无需传参
static void Show_ButtonList(void)
{
	Button_t* p=Head_Button;
	//printf("ADDR::NewNode:%08x-Head:%08x\n",p, &Head_Button);//不一样的！说明p Head_Button的内存地址不同 他们是指向相同而已！head不会变化的
	while(p)
	{
		printf("Node::Add:%08x data:%d Next:%08x ## ",p,p->data,p->Next );
		p=p->Next;
	}
	printf("\n\n" );
}

//查找一个节点  依靠按键类的data判定 如果有 找到返回1  没找到返回0
static int Search_Button(Button_t* btn)
{
  struct button* pass_btn;
  for(pass_btn = Head_Button; pass_btn != NULL; pass_btn = pass_btn->Next)
  {
    if(pass_btn->data == btn->data)
    	return 1;
  }
  return 0;
}

//增加一个节点  成功0 失败1
static int Add_Button(Button_t* btn)
{
  if(Search_Button(btn))//找到
  	return 1;	
  btn->Next = Head_Button;
  Head_Button = btn;
  	return 0;
}

//删除一个节点  成功0 失败1
static int Button_Delete(Button_t *btn)
{
  struct button** curr;
  if(Search_Button(btn)==0)//没找到
  	return 1;	
  for(curr = &Head_Button; *curr;) 
  {
    struct button* entry = *curr;//非常巧妙 二级指针迂回保护了头没有动！
    if (entry == btn) 
    {
      *curr = entry->Next;
    } 
    else
    {
      curr = &entry->Next;
    }
  }
  return 0;
}

//翻转 返回新的头指针 请传入当前的头
Button_t *  Button_Reverse(Button_t *head)
{
  printf("1\n");
  Button_t *  newhead;
  if(head == NULL || head->Next == NULL)
    return head; 
  printf("2\n");
  newhead = Button_Reverse(head->Next);

  printf("new :%d ",newhead->data );
  head->Next->Next = head;
  head->Next=NULL;
    return newhead;
}

void testpp(void)
{
	char *str =(char *) "1A3B";
	char *head = str;
	char *p=head;
	char **q=&head;
	printf("%c--%c--%c\n",*head,*p,**q);//1 1 1 此时大家都是指向1
	p++;
	printf("%c--%c--%c\n",*head,*p,**q);//1 A 1 此时P往后指向一个了 但是不会干扰到head
	p++;  //此时P在往后走一步
	printf("%c--%c--%c\n",*head,*p,**q);//1 A 1 此时P再往后指向一个了 但是不会干扰到head
	*q=p; //二级指针可以干扰到head 但是不好加加 我们就用指向来测试吧
	printf("%c--%c--%c\n",*head,*p,**q);//2 2 2 果然大家都指向了2

}

int main()
{
  printf("%s\n","hello" );
  Show_ButtonList();
  button b1,b2,b3,b4;
  b1.data=1;
  Add_Button(&b1);
  Show_ButtonList();//1
  b2.data=2;
  Add_Button(&b2);
  Show_ButtonList();//2-1
  b3.data=3;
  Add_Button(&b3);
  Show_ButtonList();
  b4.data=4;
  Add_Button(&b4);
  Show_ButtonList();


  Button_Delete(&b3);
  Show_ButtonList();

  Head_Button = Button_Reverse(Head_Button);
  Show_ButtonList();
 // testpp();

}
//文档说明：看git的代码感觉不对劲 自己写的 
//第一：链表可以不用malloc了 就像我这些传进去的就是有内存空间的实例
//第二：static void Add_Button(Button_t* btn)这个函数我就看的不对劲 果然 中间的是可以放弃的累赘代码 就是简单的头插呀！现在做了防护！
//第三：删除函数博大精深！！！对比testpp 你看为什么test可以修改head 而删除函数没有呢？
//因为删除函数找了一个entry它是head的二级指针在往上提拉的，和head指向一样地址不一样。